package com.yy.micro.magic.core.context;

import com.yy.micro.magic.core.domain.MagicRequest;
import com.yy.micro.magic.core.domain.MagicResponse;
import com.yy.micro.magic.core.loader.impl.PlanScheduleResourceLoader;
import com.yy.micro.magic.core.model.PlanSchedule;
import com.yy.micro.magic.core.processor.MagicProcessor;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author YY
 * @version 1.0.0
 * @update 2021/9/18 9:09 下午
 * @description: 数据魔方变换引擎，通过execute方法，把MagicRequest中的源数据变换为目标数据，并返回。
 * MagicRequest中指定了源数据，执行变化的模式及变换规则的planCode。
 */
@Component
public class MagicCubeEngine {

    private Lock lock = new ReentrantLock();

    private Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    private MagicCubeContext context;


    /**
     * @description: 执行数据变换。把源数据转换为目标数据源。
     * @param request 数据变换请求，指定数据源，数据变换规则的planCode及指定MagicProcessor（目前只支持"strategy"）
     * @return {@link MagicResponse}  变换后数据集，如果变换过程中有异常，则返回异常信息。
     * @update 2021/9/18
     */
    public MagicResponse execute(MagicRequest request) {
        String planCode = request.getPlanCode();
        PlanSchedule schedule = context.getManager().getValue(PlanScheduleResourceLoader.class, planCode, PlanSchedule.class);
        MagicProcessor processor = context.getComponentManager().getProcessor(request.getProcessor());
        try {
            lock.lock();
            return processor.process(request, context);
        } finally {
            lock.unlock();
        }
    }

    public void setContext(final MagicCubeContext context) {
        this.context = context;
    }
}
